/*
 * Copyright (c) 2021 Old Dominion University. All rights reserved.
 *
 * See the NOTICE file(s) distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0
 *
 * SPDX-License-Identifier: EPL-2.0
 */

package org.eclipse.mosaic.fed.mqtt.ambassador;

import ch.qos.logback.classic.util.ContextInitializer;
import org.eclipse.mosaic.fed.mqtt.config.CMqtt;
import org.eclipse.mosaic.fed.mqtt.protocol.SimpleProtocol;
import org.eclipse.mosaic.lib.util.objects.ObjectInstantiation;
import org.eclipse.mosaic.rti.api.IllegalValueException;
import org.eclipse.mosaic.rti.api.InternalFederateException;
import org.eclipse.mosaic.rti.api.RtiAmbassador;
import org.eclipse.mosaic.rti.api.parameters.AmbassadorParameter;
import org.eclipse.mosaic.rti.api.parameters.FederateDescriptor;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;

@RunWith(MockitoJUnitRunner.class)
public class MqttAmbassadorTest {

    private static final Logger log = LoggerFactory.getLogger(MqttAmbassador.class);

    File file = new File("src/test/resources/mqtt_config.json");

    @Mock
    RtiAmbassador rtiAmbassador;

    @Before
    public void setupLogger() {
        System.setProperty(ContextInitializer.CONFIG_FILE_PROPERTY, "logback.xml");
    }

    @Test
    public void testMqttConnect() throws InternalFederateException, InstantiationException, IllegalValueException {
        AmbassadorParameter ambassadorParameter = new AmbassadorParameter("mqtt", file);

        Mockito.doNothing().when(rtiAmbassador).requestAdvanceTime(Mockito.anyLong(), Mockito.anyLong(), Mockito.anyByte());

        MqttAmbassador mqttAmbassador = new MqttAmbassador(ambassadorParameter);
        mqttAmbassador.setRtiAmbassador(rtiAmbassador);
        FederateDescriptor descriptor = new FederateDescriptor("mqtt", mqttAmbassador, (byte)50);
        mqttAmbassador.setFederateDescriptor(descriptor);

        mqttAmbassador.initialize(0, 1000000000);

        CMqtt cMqtt = new ObjectInstantiation<>(CMqtt.class, log).readFile(ambassadorParameter.configuration);
        Assert.assertEquals(cMqtt.getVehicleMove().getApplications().get(0),  "org.eclipse.mosaic.app.enterprise.obu.RealVehicleApp");
    }

    @Ignore
    @Test
    public void testPublishAndReceive() {
        Thread t2 = new Thread(() -> {
            AmbassadorParameter ambassadorParameter = new AmbassadorParameter("mqtt", file);

            MqttAmbassador mqttAmbassador = new MqttAmbassador(ambassadorParameter);
            FederateDescriptor descriptor = new FederateDescriptor("mqtt", mqttAmbassador, (byte)50);
            mqttAmbassador.setFederateDescriptor(descriptor);

            try {
                mqttAmbassador.initialize(0, 1000000000);
                int id = 1;
                while (true) {
                    SimpleProtocol simple = new SimpleProtocol(String.valueOf(id), "type", "test");
                    mqttAmbassador.publish("simple", simple, 1, false);
                    id++;
                    Thread.sleep(3000);
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });

        t2.start();

        while (true) {

        }

    }
}
